package com.jfire.socket.socketserver.transfer.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.jfire.socket.socketserver.bus.CenterSwitch;
import com.jfire.socket.socketserver.transfer.handler.accept.AcceptHandler;

@Resource
public class AioServer
{
    @Resource
    private AcceptHandler                   acceptCompleteHandler;
    private AsynchronousServerSocketChannel serverSocketChannel;
    private int                             threadNum = Runtime.getRuntime().availableProcessors() * 2;
    private Logger                          logger    = LogManager.getLogger();
    private AsynchronousChannelGroup        channelGroup;
    @Resource
    private CenterSwitch                    centerSwitch;
    @Resource
    private ServerConfig                    serverConfig;
    
    public AsynchronousServerSocketChannel getServerSocketChannel()
    {
        return serverSocketChannel;
    }
    
    /**
     * 以端口初始化server服务器。
     * 
     * @param port
     */
    public void start()
    {
        centerSwitch.init();
        try
        {
            channelGroup = AsynchronousChannelGroup.withFixedThreadPool(threadNum, new ThreadFactory() {
                private int i = 1;
                
                public Thread newThread(Runnable r)
                {
                    return new Thread(r, "服务端通信处理线程-" + i++);
                }
            });
            serverSocketChannel = AsynchronousServerSocketChannel.open(channelGroup).bind(new InetSocketAddress(serverConfig.getPort()));
            logger.info("监听启动");
            serverSocketChannel.accept(null, acceptCompleteHandler);
        }
        catch (IOException e)
        {
            logger.error("服务器启动失败", e);
            throw new RuntimeException(e);
        }
    }
    
    public void stop()
    {
        try
        {
            if (channelGroup != null)
            {
                channelGroup.shutdownNow();
                channelGroup.awaitTermination(10, TimeUnit.SECONDS);
            }
            centerSwitch.stop();
            logger.info("服务器关闭");
        }
        catch (Exception e)
        {
            logger.error("关闭服务器失败", e);
            throw new RuntimeException(e);
        }
    }
}
